package service

import (
	"context"
	"errors"
	"fmt"
	"time"
	"gitee.com/chunanyong/logger"
	"gitee.com/chunanyong/zorm"
	"code/structs"
)

//SaveAccountStruct 保存 账户
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func SaveAccountStruct(ctx context.Context, accountstruct *structs.AccountStruct) error {

    // accountstruct对象指针不能为空
	if  accountstruct == nil {
		return errors.New("accountstruct对象指针不能为空")
	}
    //匿名函数return的error如果不为nil,事务就会回滚
	_, errSaveAccountStruct := zorm.Transaction(ctx,func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		

		_,errSaveAccountStruct := zorm.Insert(ctx, accountstruct)

		if errSaveAccountStruct != nil {
			return nil, errSaveAccountStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errSaveAccountStruct != nil {
		errSaveAccountStruct := fmt.Errorf("service.SaveAccountStruct错误:%w", errSaveAccountStruct)
		logger.Error(errSaveAccountStruct)
		return errSaveAccountStruct
	}

	return nil
}

//UpdateAccountStruct 更新账户
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateAccountStruct(ctx context.Context, accountstruct *structs.AccountStruct) error {


	// accountstruct对象指针或主键Id不能为空
	if  accountstruct == nil || len(accountstruct.Id) < 1 {
		return errors.New("accountstruct对象指针或主键Id不能为空")
	}

    //匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateAccountStruct := zorm.Transaction(ctx,func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_,errUpdateAccountStruct := zorm.Update(ctx, accountstruct)


		if errUpdateAccountStruct != nil {
			return nil, errUpdateAccountStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateAccountStruct != nil {
		errUpdateAccountStruct := fmt.Errorf("service.UpdateAccountStruct错误:%w", errUpdateAccountStruct)
		logger.Error(errUpdateAccountStruct)
		return errUpdateAccountStruct
	}

	return nil
}

//UpdateNotZeroAccountStruct 更新账户
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateNotZeroAccountStruct(ctx context.Context, accountstruct *structs.AccountStruct) error {

	// accountstruct对象指针或主键Id不能为空
    if  accountstruct == nil || len(accountstruct.Id) < 1 {
    	return errors.New("accountstruct对象指针或主键Id不能为空")
    }

    //匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateAccountStruct := zorm.Transaction(ctx,func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_,errUpdateAccountStruct := zorm.UpdateNotZeroValue(ctx, accountstruct)


		if errUpdateAccountStruct != nil {
			return nil, errUpdateAccountStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateAccountStruct != nil {
		errUpdateAccountStruct := fmt.Errorf("service.UpdateNotZeroAccountStruct错误:%w", errUpdateAccountStruct)
		logger.Error(errUpdateAccountStruct)
		return errUpdateAccountStruct
	}

    return nil
}

//DeleteAccountStructById 根据Id删除账户
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func DeleteAccountStructById(ctx context.Context, id string) error {


	//id不能为空
	if len(id) < 1 {
		return errors.New("id不能为空")
	}

    //匿名函数return的error如果不为nil,事务就会回滚
	_, errDeleteAccountStruct := zorm.Transaction(ctx,func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		finder := zorm.NewDeleteFinder(structs.AccountStructTableName).Append(" WHERE id=?", id)
		_,errDeleteAccountStruct := zorm.UpdateFinder(ctx, finder)


		if errDeleteAccountStruct != nil {
			return nil, errDeleteAccountStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

    //记录错误
	if errDeleteAccountStruct != nil {
		errDeleteAccountStruct := fmt.Errorf("service.DeleteAccountStruct错误:%w", errDeleteAccountStruct)
		logger.Error(errDeleteAccountStruct)
		return errDeleteAccountStruct
	}

	return nil
}

//FindAccountStructById 根据Id查询账户信息
//ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindAccountStructById(ctx context.Context, id string) (*structs.AccountStruct, error) {
	//id不能为空
	if len(id) < 1 {
		return nil, errors.New("id不能为空")
	}

	//根据Id查询
	finder := zorm.NewSelectFinder(structs.AccountStructTableName).Append(" WHERE id=?", id)
	accountstruct := structs.AccountStruct{}
	has, errFindAccountStructById := zorm.QueryRow(ctx, finder, &accountstruct)

	//记录错误
	if errFindAccountStructById != nil {
		errFindAccountStructById := fmt.Errorf("service.FindAccountStructById错误:%w", errFindAccountStructById)
		logger.Error(errFindAccountStructById)
		return nil, errFindAccountStructById
	}

    if !has {
		return nil,nil
	}


	return &accountstruct, nil

}

//FindAccountStructList 根据Finder查询账户列表
//ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindAccountStructList(ctx context.Context, finder *zorm.Finder, page *zorm.Page) ([]structs.AccountStruct, error) {

	//finder不能为空
	if finder == nil {
		return nil, errors.New("finder不能为空")
	}

	accountstructList := make([]structs.AccountStruct, 0)
	errFindAccountStructList := zorm.Query(ctx, finder, &accountstructList, page)

	//记录错误
	if errFindAccountStructList != nil {
		errFindAccountStructList := fmt.Errorf("service.FindAccountStructList错误:%w", errFindAccountStructList)
		logger.Error(errFindAccountStructList)
		return nil, errFindAccountStructList
	}

	return accountstructList, nil
}
